home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / Examples / Draw / Sources / DrawFrm.cpp < prev    next >
Encoding:
Text File  |  1995-11-08  |  25.7 KB  |  821 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                DrawFrm.cpp
  4. //    Release Version:    $ 1.0d11 $
  5. //
  6. //    Author:                Henri Lamiraux
  7. //
  8. //    Copyright:    © 1993, 1995 by Apple Computer, Inc., all rights reserved.
  9. //
  10. //========================================================================================
  11.  
  12. #include "ODFDraw.hpp"
  13.  
  14. #ifndef DRAWFRM_H
  15. #include "DrawFrm.h"
  16. #endif
  17.  
  18. #ifndef DRAWDEF_H
  19. #include "DrawDef.h"
  20. #endif
  21.  
  22. #ifndef DRAWPART_H
  23. #include "DrawPart.h"
  24. #endif
  25.  
  26. #ifndef DRAWVIEW_H
  27. #include "DrawView.h"
  28. #endif
  29.  
  30. #ifndef EDITCMDS_H
  31. #include "EditCmds.h"
  32. #endif
  33.  
  34. #ifndef DRAWSEL_H
  35. #include "DrawSel.h"
  36. #endif
  37.  
  38. #ifndef DRAWPRXY_H
  39. #include "DrawPrxy.h"
  40. #endif
  41.  
  42. #ifndef SHPTRAKR_H
  43. #include "ShpTrakr.h"
  44. #endif
  45.  
  46. #ifndef DRAWCMDS_H
  47. #include "DrawCmds.h"
  48. #endif
  49.  
  50. #ifndef DRAWCLIP_H
  51. #include "DrawClip.h"
  52. #endif
  53.  
  54. #ifndef UTILS_H
  55. #include "Utils.h"
  56. #endif
  57.  
  58. #ifndef DRWDDCMD_H
  59. #include "DrwDDCmd.h"
  60. #endif
  61.  
  62. #ifndef FWRULER_H
  63. #include "FWRuler.h"
  64. #endif
  65.  
  66. // ----- Framework Layer -----
  67.  
  68. #ifndef FWUTIL_H
  69. #include "FWUtil.h"
  70. #endif
  71.  
  72. #ifndef FWPRESEN_H
  73. #include "FWPresen.h"
  74. #endif
  75.  
  76. #ifndef FWSCROLR_H
  77. #include "FWScrolr.h"
  78. #endif
  79.  
  80. #ifndef FWSCLBAR_H
  81. #include "FWSclBar.h"
  82. #endif
  83.  
  84. #ifndef FWGROWBX_H
  85. #include "FWGrowBx.h"
  86. #endif
  87.  
  88. #ifndef FWPRHDLR_H
  89. #include "FWPrHdlr.h"
  90. #endif
  91.  
  92. // ----- OS Layer -----
  93.  
  94. #ifndef FWMENU_H
  95. #include "FWMenu.h"
  96. #endif
  97.  
  98. #ifndef FWRECSHP_H
  99. #include "FWRecShp.h"
  100. #endif
  101.  
  102. #ifndef FWCURSOR_H
  103. #include "FWCursor.h"
  104. #endif
  105.  
  106. #ifndef FWEVENT_H
  107. #include "FWEvent.h"
  108. #endif
  109.  
  110. #ifndef FWODGEOM_H
  111. #include "FWODGeom.h"
  112. #endif
  113.  
  114. #ifndef FWLINSHP_H
  115. #include "FWLinShp.h"
  116. #endif
  117.  
  118. #ifndef FWBMPSHP_H
  119. #include "FWBmpShp.h"
  120. #endif
  121.  
  122. // ----- OpenDoc Includes -----
  123.  
  124. #ifndef SOM_Module_OpenDoc_Commands_defined
  125. #include <CmdDefs.xh>
  126. #endif
  127.  
  128. #ifndef SOM_Module_OpenDoc_StdProps_defined
  129. #include <StdProps.xh>
  130. #endif
  131.  
  132. #ifndef SOM_ODSession_xh
  133. #include <ODSessn.xh>
  134. #endif
  135.  
  136. #ifndef SOM_ODDispatcher_xh
  137. #include <Disptch.xh>
  138. #endif
  139.  
  140. //========================================================================================
  141. // RunTime Info
  142. //========================================================================================
  143.  
  144. #ifdef FW_BUILD_MAC
  145. #pragma segment odfdrawframes
  146. #endif
  147.  
  148. FW_DEFINE_CLASS_M1(CDrawFrame, FW_CEmbeddingFrame);
  149.  
  150. //========================================================================================
  151. // CDrawFrame
  152. //========================================================================================
  153.  
  154. //----------------------------------------------------------------------------------------
  155. // CDrawFrame::CDrawFrame
  156. //----------------------------------------------------------------------------------------
  157.  
  158. CDrawFrame::CDrawFrame(Environment* ev, ODFrame* odFrame, FW_CPresentation* presentation, CDrawPart* drawPart) :
  159.     FW_CEmbeddingFrame(ev, odFrame, presentation, drawPart),
  160.     fDrawPart(drawPart),
  161.     fGrowBox(NULL),
  162.     fSelection((CDrawSelection*)GetPresentation(ev)->GetSelection(ev)),
  163.     fHorzRuler(NULL),
  164.     fVertRuler(NULL),
  165.     fGridShown(TRUE),
  166.     fRulersShown(TRUE)
  167.  
  168. {    
  169.     this->SetDroppable(ev, TRUE);
  170. }
  171.  
  172. //----------------------------------------------------------------------------------------
  173. // CDrawFrame::~CDrawFrame
  174. //----------------------------------------------------------------------------------------
  175.  
  176. CDrawFrame::~CDrawFrame()
  177. {
  178. }
  179.  
  180. //----------------------------------------------------------------------------------------
  181. //    CDrawFrame::DoAdjustMenus
  182. //----------------------------------------------------------------------------------------
  183.  
  184. FW_Boolean CDrawFrame::DoAdjustMenus(Environment* ev, FW_CMenuBar* menuBar, FW_Boolean hasMenuFocus, FW_Boolean isRoot)
  185. {
  186.     // ----- Edit Menu -----
  187.     if (hasMenuFocus)
  188.     {
  189.         menuBar->EnableCommand(ev, kODCommandPaste, HasPropertyOnClipboard(ev, kODPropContents, NULL)); // we don't care about the type
  190.         
  191.         menuBar->EnableAndToggleCommand(ev, cGraphicsGrid, TRUE, fGridShown);
  192.         menuBar->EnableAndToggleCommand(ev, cRulers, TRUE, fRulersShown);
  193.     }
  194.     
  195.     return FALSE;
  196. }
  197.  
  198. //----------------------------------------------------------------------------------------
  199. //    CDrawFrame::DoMenu
  200. //----------------------------------------------------------------------------------------
  201.  
  202. FW_Boolean CDrawFrame::DoMenu(Environment* ev, const FW_CMenuEvent& theMenuEvent)
  203. {
  204.     FW_Boolean handled = TRUE;
  205.     
  206.     switch (theMenuEvent.GetCommandID(ev))
  207.     {
  208.         case cGraphicsGrid:
  209.             fGridShown = !fGridShown;
  210.             GetContentView(ev)->Invalidate(ev);
  211.             break;
  212.         
  213.         case cRulers:
  214.             fRulersShown = !fRulersShown;
  215.             ToggleRulers(ev, fRulersShown);
  216.             Invalidate(ev);
  217.             break;
  218.             
  219.         default:
  220.             handled = FALSE;
  221.     }
  222.     
  223.     return handled;
  224. }
  225.  
  226. //----------------------------------------------------------------------------------------
  227. //    CDrawFrame::NewEditCommand
  228. //----------------------------------------------------------------------------------------
  229. FW_CEditCommand* CDrawFrame::NewEditCommand(Environment* ev, ODCommandID commandID)    // Override
  230. {
  231. #if defined(FW_BUILD_WIN) && FW_OPENDOC_VERSION == FW_OPENDOC_DR1
  232.     FW_Boolean undoAble = FALSE;
  233. #else
  234.     FW_Boolean undoAble = TRUE;
  235. #endif
  236.  
  237.     return FW_NEW(CDrawEditCommand, (ev, commandID, fDrawPart, this, fSelection, undoAble));
  238. }
  239.  
  240. //----------------------------------------------------------------------------------------
  241. //    CDrawFrame::DoActivateEvent
  242. //----------------------------------------------------------------------------------------
  243.  
  244. FW_Boolean CDrawFrame::DoActivateEvent(Environment* ev, const FW_CActivateEvent& theActivateEvent)
  245. {
  246. //    if (IsActive(ev))
  247. //        fSelection->DrawAllHandles(ev, this, theActivateEvent.IsActivating(ev));
  248.     
  249.     return FALSE;
  250. }
  251.  
  252. //----------------------------------------------------------------------------------------
  253. //    CDrawFrame::AdjustZoomedWindowSize
  254. //----------------------------------------------------------------------------------------
  255.  
  256. void CDrawFrame::AdjustZoomedWindowSize(Environment* ev, FW_CPoint& proposedSize)
  257. {
  258.     proposedSize = fDrawPart->GetDrawingSize();
  259. }
  260.  
  261. //----------------------------------------------------------------------------------------
  262. //    CDrawFrame::AdjustWindowGrowLimits
  263. //----------------------------------------------------------------------------------------
  264.  
  265. void CDrawFrame::AdjustWindowGrowLimits(Environment* ev, FW_CPoint& minSize, FW_CPoint& maxSize)
  266. {
  267.     FW_CPoint sbSize = FW_CScrollBar::GetDefaultScrollBarSize();
  268.  
  269.     minSize.x = FW_IntToFixed(72) + sbSize.x;
  270.     minSize.y = FW_IntToFixed(72) + sbSize.y;
  271. }
  272.  
  273. //----------------------------------------------------------------------------------------
  274. //    CDrawFrame::GeometryChanged
  275. //----------------------------------------------------------------------------------------
  276. //    the geometry (clip shape, external or Internal transform) of one of my facet or one of my
  277. //    embedding facet as changed
  278.  
  279. void CDrawFrame::GeometryChanged(Environment *ev,
  280.                                 ODFacet* odFacet,
  281.                                 FW_Boolean clipShapeChanged,
  282.                                 FW_Boolean externalTransformChanged)
  283. {
  284.     FW_CEmbeddingFrame::GeometryChanged(ev, odFacet, clipShapeChanged, externalTransformChanged);
  285.     
  286.     if (externalTransformChanged)
  287.     {
  288.         CDrawFacetClipper facetClipper(ev, fDrawPart);
  289.         facetClipper.ClipEmbeddedFacets(ev, this, odFacet, NULL);
  290.     }
  291. }
  292.  
  293. //----------------------------------------------------------------------------------------
  294. //    CDrawFrame::FrameShapeChanged
  295. //----------------------------------------------------------------------------------------
  296. //    My Frame shape has changed I need to clip my embedded facets
  297.  
  298. void CDrawFrame::FrameShapeChanged(Environment *ev)
  299. {
  300.     FW_CEmbeddingFrame::FrameShapeChanged(ev);
  301.     
  302.     CDrawFacetClipper facetClipper(ev, fDrawPart);
  303.     facetClipper.Clip(ev, this, NULL);
  304. }
  305.  
  306. //----------------------------------------------------------------------------------------
  307. //    CDrawFrame::CreateEmbeddedFacet
  308. //----------------------------------------------------------------------------------------
  309.  
  310. FW_DECLARE_THROW_POINT (CDrawFrame_CreateEmbeddedFacet);
  311.  
  312. ODFacet* CDrawFrame::CreateEmbeddedFacet(Environment* ev,
  313.                                         ODFacet* embeddingFacet,
  314.                                         FW_MProxy* proxy,
  315.                                         ODFrame* embeddedFrame,
  316.                                         ODShape* proposedClipShape)
  317. {
  318.     FW_CRect embeddedFrameBounds = ((CProxyShape*)proxy)->GetFrameRect(ev);
  319.     
  320.     FW_CAcquiredODTransform aqExternalTransform = ::FW_NewODTransform(ev, embeddedFrameBounds.TopLeft());
  321.  
  322.     FW_CHECK_THROW_POINT (CDrawFrame_CreateEmbeddedFacet);
  323.     return embeddingFacet->CreateEmbeddedFacet(ev,
  324.                                                 embeddedFrame,
  325.                                                 proposedClipShape,
  326.                                                 aqExternalTransform,
  327.                                                 NULL,                    // Canvas
  328.                                                 NULL,                    // biasCanvas
  329.                                                 NULL,                    // siblingFacet
  330.                                                 kODFrameInFront);
  331. }
  332.  
  333. //----------------------------------------------------------------------------------------
  334. // CDrawFrame::CreateSubViews
  335. //----------------------------------------------------------------------------------------
  336.  
  337. const FW_CFixed kRulerWidth = FW_IntToFixed(15);    
  338.  
  339. void CDrawFrame::CreateSubViews(Environment* ev)
  340. {        
  341.     FW_CRect frameRect = GetBounds(ev);    
  342.     FW_CRect contentRect(frameRect);
  343.  
  344.     FW_CPoint sbSize = FW_CScrollBar::GetDefaultScrollBarSize();
  345.     
  346.     if (fRulersShown) {
  347.         // Make space for rulers
  348.         contentRect.top += kRulerWidth;
  349.         contentRect.left += kRulerWidth;
  350.     }
  351.     
  352.     if (this->IsRoot(ev))
  353.     {
  354.         // Make space for scrollbars
  355.         contentRect.bottom -= sbSize.y;
  356.         contentRect.right -= sbSize.x;
  357.     }
  358.     
  359.     FW_CPoint drawingSize = fDrawPart->GetDrawingSize();
  360.     
  361.     // ----- Create the content view
  362.     CDrawView* contentView = new CDrawView(ev, this, contentRect, fDrawPart);
  363.     contentView->MakeContentView(ev);
  364.     contentView->SetExtent(ev, drawingSize);    // Set the content's extent
  365.  
  366.     // ----- Create scroll bars and grow box in root frame only -----
  367.     if (this->IsRoot(ev))
  368.     {    
  369.         // ----- Create the vertical scroll bar
  370.         FW_CRect vertSbRect(contentRect.right, 
  371.                                 frameRect.top - FW_kFixedPos1, 
  372.                                 contentRect.right + sbSize.x + FW_kFixedPos1, 
  373.                                 contentRect.bottom + FW_kFixedPos1);
  374.         FW_CScrollBar* vertSB = new FW_CScrollBar(ev, this, 0, vertSbRect);
  375. //        AdjustMinorScrollUnits(ev, vertSB, contentRect.Height());
  376.         
  377.         // ----- Create the horizontan scroll bar
  378.         FW_CRect horzSbRect(frameRect.left - FW_kFixedPos1, 
  379.                                 contentRect.bottom, 
  380.                                 contentRect.right + FW_kFixedPos1, 
  381.                                 contentRect.bottom + sbSize.y + FW_kFixedPos1);
  382.         FW_CScrollBar* horzSB = new FW_CScrollBar(ev, this, 0, horzSbRect);
  383. //        AdjustMinorScrollUnits(ev, horzSB, contentRect.Width());
  384.         
  385.         // ----- Create the GrowBox gadget
  386.         fGrowBox = new FW_CGrowBox(ev, this, 0, contentRect.BotRight());
  387.  
  388.         // ----- add a scroller to content view -----
  389.         contentView->AddScrollBarScroller(ev, horzSB, vertSB);
  390.     }
  391.     
  392.     // ----- Create the rulers
  393.      FW_CRect HorzRulerRect(contentRect.left, contentRect.top - kRulerWidth,
  394.                          contentRect.right, contentRect.top);
  395.     fHorzRuler = new FW_CRuler(ev, this, HorzRulerRect, FW_CView::kXaxis);
  396.     FW_CPoint horzRulerExtent(drawingSize.x, kRulerWidth);
  397.     fHorzRuler->SetExtent(ev, horzRulerExtent);    // Set the content's extent
  398.  
  399.      FW_CRect VertRulerRect(contentRect.left - kRulerWidth, contentRect.top,
  400.                          contentRect.left, contentRect.bottom);
  401.     fVertRuler = new FW_CRuler(ev, this, VertRulerRect, FW_CView::kYaxis);
  402.     FW_CPoint vertRulerExtent(kRulerWidth, drawingSize.y);
  403.     fVertRuler->SetExtent(ev, vertRulerExtent);    // Set the content's extent
  404.  
  405.     if (!fRulersShown) {
  406.         fHorzRuler->SetVisible(ev, FALSE);
  407.         fVertRuler->SetVisible(ev, FALSE);
  408.     }
  409. }
  410.  
  411. //----------------------------------------------------------------------------------------
  412. // CDrawFrame::AdjustSubViews
  413. //----------------------------------------------------------------------------------------
  414.  
  415. void CDrawFrame::AdjustSubViews(Environment* ev)
  416. {
  417.     FW_CRect frameRect = GetBounds(ev);    
  418.     FW_CRect contentRect(frameRect);
  419.  
  420.     FW_CView* contentView = GetContentView(ev);
  421.     FW_ASSERT(contentView != NULL);
  422.  
  423.     if (fRulersShown) {
  424.         // Make space for rulers
  425.         contentRect.top += kRulerWidth;
  426.         contentRect.left += kRulerWidth;
  427.     }
  428.  
  429.     if (IsRoot(ev))
  430.     {
  431.         FW_CPoint sbSize = FW_CScrollBar::GetDefaultScrollBarSize();
  432.     
  433.         // Get scroller from content view
  434.         FW_CScrollBarScroller* scroller = (FW_CScrollBarScroller*)contentView->GetScroller(ev);
  435.         FW_CScrollBar* scrollBar;
  436.         
  437.         contentRect.bottom -= sbSize.y;
  438.         contentRect.right -= sbSize.x;
  439.     
  440.         // adjust bounds of gadgets & invalidate old/new positions to force redrawing
  441.         if (scrollBar = scroller->GetScrollBar(ev, FW_CScrollBarScroller::kVertical))
  442.         {
  443.             scrollBar->Invalidate(ev);    
  444.             scrollBar->SetLocation(ev, FW_CPoint(contentRect.right, frameRect.top - FW_kFixedPos1));
  445.             scrollBar->SetSize(ev, FW_CPoint(sbSize.x + FW_kFixedPos1, contentRect.bottom - frameRect.top + FW_kFixedPos1 + FW_kFixedPos1));
  446.             scrollBar->Invalidate(ev);    
  447. //            AdjustMinorScrollUnits(ev, scrollBar, contentRect.Height());
  448.         }
  449.         
  450.         if (scrollBar = scroller->GetScrollBar(ev, FW_CScrollBarScroller::kHorizontal))
  451.         {
  452.             scrollBar->Invalidate(ev);    
  453.             scrollBar->SetLocation(ev, FW_CPoint(frameRect.left - FW_kFixedPos1, contentRect.bottom));
  454.             scrollBar->SetSize(ev, FW_CPoint(contentRect.right - frameRect.left + FW_kFixedPos1 + FW_kFixedPos1, sbSize.y + FW_kFixedPos1));
  455.             scrollBar->Invalidate(ev);    
  456. //            AdjustMinorScrollUnits(ev, scrollBar, contentRect.Width());
  457.         }
  458.         
  459.         if (fGrowBox)
  460.         {
  461.             fGrowBox->Invalidate(ev);    
  462.             fGrowBox->SetLocation(ev, contentRect.BotRight());
  463.             fGrowBox->Invalidate(ev);    
  464.         }
  465.         
  466.         scroller->UpdateScrollParameters(ev);
  467.     }
  468.     
  469.     if (fRulersShown) {
  470.         // adjust rulers
  471.         if (fHorzRuler) {
  472.             fHorzRuler->SetSize(ev, FW_CPoint(contentRect.right - contentRect.left, kRulerWidth));
  473.         }
  474.         if (fVertRuler) {
  475.             fVertRuler->SetSize(ev, FW_CPoint(kRulerWidth, contentRect.bottom - contentRect.top));        
  476.         }
  477.     }
  478.     
  479.     contentView->SetSize(ev, contentRect.Size());
  480. }
  481.  
  482. //----------------------------------------------------------------------------------------
  483. //    CDrawFrame::NewDragCommand
  484. //----------------------------------------------------------------------------------------
  485.  
  486. FW_CDragCommand* CDrawFrame::NewDragCommand(Environment *ev, FW_CFrame* theFrame)
  487. {
  488.     CDragCommand* dragCommand = FW_NEW(CDragCommand,
  489.                                             (ev, fDrawPart, theFrame,
  490.                                             fSelection,
  491.                                             FW_kCanUndo));
  492.     return (FW_CDragCommand*) dragCommand;
  493. }
  494.  
  495. //----------------------------------------------------------------------------------------
  496. //    CDrawFrame::NewDropCommand
  497. //----------------------------------------------------------------------------------------
  498. FW_CDropCommand* CDrawFrame::NewDropCommand(Environment *ev,
  499.                                             FW_CFrame* frame,
  500.                                             ODDragItemIterator* dropInfo, 
  501.                                             ODFacet* facet, 
  502.                                             const FW_CPoint& dropPoint)
  503. {
  504.     CDropCommand* dropCommand = FW_NEW(CDropCommand,
  505.                                             (ev, fDrawPart, frame,
  506.                                             dropInfo, facet, dropPoint,
  507.                                             FW_kCanUndo));
  508.     return (FW_CDropCommand*) dropCommand;
  509. }
  510.  
  511. //----------------------------------------------------------------------------------------
  512. //    CDrawFrame::ToggleRulers
  513. //----------------------------------------------------------------------------------------
  514.  
  515. void CDrawFrame::ToggleRulers(Environment *ev, FW_Boolean visible)
  516. {
  517.     FW_ASSERT(fHorzRuler != NULL && fVertRuler != NULL);
  518.     fHorzRuler->SetVisible(ev, visible);
  519.     fVertRuler->SetVisible(ev, visible);
  520.         
  521.     // updates the contentView bounds
  522.     FW_CRect contentRect = GetBounds(ev);
  523.     FW_CView* contentView = GetContentView(ev);
  524.     if (IsRoot(ev)) {
  525.         FW_CPoint sbSize = FW_CScrollBar::GetDefaultScrollBarSize();
  526.         contentRect.bottom -= sbSize.y;
  527.         contentRect.right -= sbSize.x;    
  528.     }
  529.  
  530.     if (visible) {
  531.         contentRect.top += kRulerWidth;
  532.         contentRect.left += kRulerWidth;
  533.         contentView->SetLocation(ev, contentRect.TopLeft());
  534.     }
  535.     else {
  536.         contentView->SetLocation(ev, contentRect.TopLeft());
  537.     }
  538.     contentView->SetSize(ev, contentRect.Size());
  539. }
  540.  
  541. //----------------------------------------------------------------------------------------
  542. //    CDrawFrame::EmbedSingleFrame
  543. //----------------------------------------------------------------------------------------
  544.  
  545. FW_DECLARE_THROW_POINT (DrawFrameEmbedSingleFrame1);
  546. FW_DECLARE_THROW_POINT (DrawFrameEmbedSingleFrame2);
  547. FW_DECLARE_THROW_POINT (DrawFrameEmbedSingleFrame3);
  548.  
  549. void CDrawFrame::EmbedSingleFrame(Environment* ev, 
  550.                                 ODPart* embeddedPart, 
  551.                                 ODFrame* embeddedFrame,
  552.                                 ODShape* frameShape)
  553. {
  554. /*
  555.     *** Let's think about failure handling here.
  556.     
  557.     Just throwing exceptions isn't enough. Looking through this method we can see *lots* of
  558.     methods which perform state changes. If any exception was thrown before all state 
  559.     changes were complete we'd wind up with a document in a very sorry state. And since
  560.     embedding is an expensive (memory-requiring) process we have a good chance of failures
  561.     occuring.
  562.     
  563.     When an error occurs, proper cleanup would make it look as though we had never entered
  564.     the method in the first place. That means if several state changes are required,
  565.     cleaning up after an exception requires us to *undo* all state changes up to the point
  566.     where we failed. So we need to look at each line and determine if it makes a state
  567.     change which needs to be "protected" from subsequent possible failures. Anything after
  568.     a state change which is deemed "dangerous" is wrapped in a try/catch block, like so:
  569.         <state change 1>
  570.         try {
  571.             <state change 2>
  572.         } catch (...) {
  573.             <undo state change 1>
  574.         }
  575.     
  576.     Step 1: "fSelection->CloseSelection". This deselects everything. It is a state change
  577.     but it's not important - i.e. it's not important for us to restore the selection if an
  578.     exception occurs later. So we don't have to protect it.
  579.     
  580.     Steps 2 to 4: these are safe; everything is on the stack and doesn't change state,
  581.     or, in the case of "FW_CAcquiredODShape aqFrameShape = ...", the destructor will 
  582.     clean up for us in the event of an exception being thrown.
  583.     
  584.     Step 5: "new CProxyShape" requires cleanup. We're allocating something on the heap here;
  585.     suppose the very next line threw an exception? In that case we would fail to properly 
  586.     dispose of it, and would have a memory leak. Therefore we put everything *after* the
  587.     allocation inside a try/catch block.
  588.     
  589.     Step 6: "AddShape" also requires cleanup. We're presuming that we will complete the embed
  590.     process. If we don't then having this pointer in the shape list would be bad.
  591.     
  592.     Step 7: This is the important bit, but if it fails we don't worry. Whoever called us will
  593.     deal with it. What's important is that none of the other *preperatory* state changes we had
  594.     to make to support this step will be forgotten.
  595.     
  596.     Step 8: This is another thing which can throw but this one isn't important. If we can't
  597.     select the newly-added shape then so what? - we were able to embed the part, which is what
  598.     matters. Wrap in try/catch to suppress a misleading "out of memory" alert box.
  599. */
  600.     // ----- Step 1: Close the current selection -----
  601.     fSelection->CloseSelection(ev);
  602.     
  603.     // ----- Step 2: Calculate the default shape rect
  604.     FW_CRect shapeRect;
  605.     if (frameShape)
  606.     {
  607.         shapeRect = FW_GetShapeBoundingBox(ev, frameShape);
  608.         shapeRect.Offset(-shapeRect.left, -shapeRect.top);
  609.     }
  610.     else
  611.     {
  612.         shapeRect.SetInt(0, 0, 80, 80);
  613.     }
  614.  
  615.     // ----- Step 3: Calculate the shape of the embedded frame -----    
  616.     FW_CAcquiredODShape aqFrameShape = ::FW_NewODShape(ev, shapeRect);
  617.     
  618.     // ----- Step 4: Calculate its position -----
  619.     // ----- We placing it in the middle of the content view -----
  620.     FW_CRect frameBounds = GetContentView(ev)->GetBounds(ev);
  621.     frameBounds.Place(FW_kFixed0, FW_kFixed0);
  622.     GetContentView(ev)->ViewToViewContent(ev, frameBounds);
  623.     shapeRect.PlaceInCenter(frameBounds);
  624.     
  625.     // ----- Step 5: Create the proxy shape -----
  626.     CProxyShape* proxyShape = new CProxyShape(ev, shapeRect, fDrawPart);
  627.     // make sure that if an exception occurs before we complete this method that
  628.     // we dispose of the shape
  629.     FW_TRY {
  630.     
  631.         // Step 6: ----- Add the shape to the list of shape -----
  632.         FW_CHECK_THROW_POINT (DrawFrameEmbedSingleFrame1);
  633.         fDrawPart->AddShape(ev, proxyShape);
  634.         // this is another state change which needs cleanup. This is kind of screwy
  635.         // actually - why are we adding the shape before we've embedded it? Probably
  636.         // the following code will require this. Therefore we need to ensure that if
  637.         // for some reason we fail to embed that we remove the now-unused shape.
  638.         FW_TRY {
  639.         
  640.             // Step 7: ----- Embed the Part/Frame -----
  641.             FW_CHECK_THROW_POINT (DrawFrameEmbedSingleFrame2);
  642.             GetPresentation(ev)->Embed(ev, 
  643.                                 embeddedPart, 
  644.                                 embeddedFrame,
  645.                                 proxyShape,
  646.                                 aqFrameShape,
  647.                                 FW_CPart::gViewAsFrameToken,
  648.                                 NULL,        // no presentation
  649.                                   0,            // groupe id
  650.                                   FALSE);        // sub frame
  651.         }
  652.         FW_CATCH_BEGIN
  653.         FW_CATCH_EVERYTHING () {
  654.             // cleanup for Step 6 - since embedding failed we don't want this shape pointer dangling
  655.             fDrawPart->RemoveShape (ev, proxyShape);
  656.             FW_THROW_SAME ();
  657.         }
  658.         FW_CATCH_END
  659.     }
  660.     FW_CATCH_BEGIN
  661.     FW_CATCH_EVERYTHING () {
  662.         // cleanup for Step 5
  663.         delete proxyShape;
  664.         FW_THROW_SAME ();
  665.     }
  666.     FW_CATCH_END
  667.     
  668.     // Step 8: ----- Add it to the selection -----
  669.     // Theoretically AddToSelection could throw (since it allocates memory)
  670.     // but since all it does is select the newly added shape we don't care
  671.     // if it fails. It's not worth aborting the entire embed process just because
  672.     // we couldn't make it select. It would also be strange to see an "out of memory"
  673.     // error box come up after embedding when it *did* embed ok.
  674.     FW_TRY {
  675.         FW_CHECK_THROW_POINT (DrawFrameEmbedSingleFrame3);
  676.         fSelection->AddToSelection(ev, proxyShape, FALSE);
  677.     }
  678.     FW_CATCH_BEGIN
  679.     FW_CATCH_EVERYTHING () {
  680.         // do nothing, do NOT rethrow
  681.     }
  682.     FW_CATCH_END
  683. }
  684.  
  685. //----------------------------------------------------------------------------------------
  686. //    CDrawFrame::Draw
  687. //----------------------------------------------------------------------------------------
  688.  
  689. void CDrawFrame::Draw(Environment *ev, ODFacet* odFacet, ODShape* invalidShape)
  690. {
  691.     // The only thing to draw is the top left corner box
  692.     if (fRulersShown)
  693.     {
  694.         FW_CViewContext vc(ev, this, odFacet, invalidShape);
  695.         FW_CRect box(FW_kFixedNeg1, FW_kFixedNeg1, kRulerWidth, kRulerWidth);
  696.         FW_CRectShape::RenderRect(vc, box, FW_kFill, FW_kWhiteEraseInk);
  697.         FW_CRectShape::RenderRect(vc, box, FW_kFrame);
  698.     }
  699. }
  700.  
  701. //----------------------------------------------------------------------------------------
  702. //    CDrawFrame::NewPrintHandler
  703. //----------------------------------------------------------------------------------------
  704.  
  705. FW_CPrintHandler* CDrawFrame::NewPrintHandler(Environment* ev)
  706. {
  707.     FW_CPart* part = GetPart(ev);
  708.     return new FW_CPrintHandler(part, this);
  709. }
  710.  
  711. //----------------------------------------------------------------------------------------
  712. //    CDrawFrame::IsCurrentlyPrintable
  713. //----------------------------------------------------------------------------------------
  714.  
  715. FW_Boolean CDrawFrame::IsCurrentlyPrintable(Environment* ev) const
  716. {
  717.     FW_CPrivOrderedCollection* shapeList = fDrawPart->GetShapeList();
  718.     return shapeList->Count() != 0;
  719. }
  720.  
  721. //----------------------------------------------------------------------------------------
  722. //    CDrawFrame::GetPrintContentExtent
  723. //----------------------------------------------------------------------------------------
  724.  
  725. void CDrawFrame::GetPrintContentExtent(Environment *ev, FW_CPoint& extent) const
  726. {
  727.     // We only enable print command if there is anything to print
  728.     FW_ASSERT(fDrawPart->GetShapeList()->Count() != 0);
  729.  
  730.     // Go through all the shapes and determine their bounds
  731.     extent.Set(FW_kFixed0, FW_kFixed0);
  732.     FW_COrderedCollectionIterator ite(fDrawPart->GetShapeList());
  733.     for (CBaseShape* theShape = (CBaseShape*)ite.First(); ite.IsNotComplete(); theShape = (CBaseShape*)ite.Next())
  734.     {
  735.         FW_CRect updateBox;
  736.         theShape->GetUpdateBox(updateBox);
  737.  
  738.         if (updateBox.right > extent.x)
  739.             extent.x = updateBox.right;
  740.         
  741.         if (updateBox.bottom > extent.y)
  742.             extent.y = updateBox.bottom;
  743.     }
  744.     
  745.     FW_ASSERT(extent.x && extent.y);
  746. }
  747.  
  748. //----------------------------------------------------------------------------------------
  749. //    CDrawFrame::RevealFrame
  750. //----------------------------------------------------------------------------------------
  751.  
  752. FW_Boolean CDrawFrame::RevealFrame(Environment *ev, 
  753.                                    ODFrame* embeddedFrame, 
  754.                                    ODShape* revealShape)
  755. {
  756.     FW_UNUSED(revealShape);
  757.  
  758.     // Look thru shape list for a proxy shape that matches the embeddedFrame
  759.     FW_COrderedCollectionIterator iter(fDrawPart->GetShapeList());
  760.     for (CBaseShape* shape = (CBaseShape*)iter.First(); iter.IsNotComplete(); shape = (CBaseShape*)iter.Next())
  761.     {
  762.         if (shape->GetShapeType() == kProxyShape)
  763.         {
  764.             CProxyShape* proxyShape = (CProxyShape*)shape;
  765.             ODFrame* proxyEmbeddedFrame = proxyShape->GetEmbeddedFrame(ev, this);
  766.             if (proxyEmbeddedFrame == embeddedFrame)
  767.             {
  768.                 // Select the proxy shape and redraw it
  769.                 fSelection->CloseSelection(ev);
  770.                 fSelection->AddToSelection(ev, proxyShape, TRUE);
  771.                 return TRUE;
  772.             }
  773.         }
  774.     }
  775.  
  776.     return FALSE;
  777. }
  778.  
  779. //----------------------------------------------------------------------------------------
  780. //    CDrawFrame::FacetAdded
  781. //----------------------------------------------------------------------------------------
  782.  
  783. void CDrawFrame::FacetAdded(Environment* ev, ODFacet* facet)
  784. {
  785.     FW_CEmbeddingFrame::FacetAdded(ev, facet);    // Call inherited
  786.  
  787.     // Perform "DoPostCreate"-type initialization here.
  788.     fDrawPart->DoPostCreate(ev);
  789. }
  790.  
  791. //----------------------------------------------------------------------------------------
  792. //    CDrawFrame::ExternalizeFrame
  793. //----------------------------------------------------------------------------------------
  794.  
  795. void CDrawFrame::ExternalizeFrame(Environment* ev, ODStorageUnitView* storageUnitView)
  796. {
  797.     FW_CEmbeddingFrame::ExternalizeFrame(ev, storageUnitView);
  798.     
  799.     FW_CStorageUnitSink sink(storageUnitView);
  800.     FW_CWritableStream stream(&sink);
  801.     
  802.     stream << fGridShown;
  803.     stream << fRulersShown;
  804. }
  805.  
  806. //----------------------------------------------------------------------------------------
  807. //    CDrawFrame::InternalizeFrame
  808. //----------------------------------------------------------------------------------------
  809.  
  810. void CDrawFrame::InternalizeFrame(Environment* ev, ODStorageUnitView* storageUnitView)
  811. {
  812.     FW_CEmbeddingFrame::InternalizeFrame(ev, storageUnitView);
  813.  
  814.     FW_CStorageUnitSink sink(storageUnitView);
  815.     FW_CReadableStream stream(&sink);
  816.     
  817.     stream >> fGridShown;
  818.     stream >> fRulersShown;
  819. }
  820.  
  821.